package com.tetris

//   ██
// ██
class Block4: Block {
    /**
     * 构造方法。
     */
    constructor() {
        mBlocks[2][1].mUsed = true
        mBlocks[2][0].mUsed = true
        mBlocks[1][2].mUsed = true
        mBlocks[1][1].mUsed = true
    }

    /**
     * 获取底端所在的行数。底端是指方块最下方的有效格。
     */
    override val bottom: Int
        get() = mRow.intValue + 2

    /**
     * 对不能下落的处理。
     */
    override fun handleCannotMoveDown() {
        when (mShape.value) {
            Shape.ONE -> {
                Game.sExistentBlocks[mRow.intValue + 2][mLine.intValue + 1].mUsed = true
                Game.sExistentBlocks[mRow.intValue + 2][mLine.intValue].mUsed = true
                Game.sExistentBlocks[mRow.intValue + 1][mLine.intValue + 2].mUsed = true
                Game.sExistentBlocks[mRow.intValue + 1][mLine.intValue + 1].mUsed = true
                Game.sExistentBlocks[mRow.intValue + 2][mLine.intValue + 1].mColor = mColor
                Game.sExistentBlocks[mRow.intValue + 2][mLine.intValue].mColor = mColor
                Game.sExistentBlocks[mRow.intValue + 1][mLine.intValue + 2].mColor = mColor
                Game.sExistentBlocks[mRow.intValue + 1][mLine.intValue + 1].mColor = mColor
            }
            Shape.TWO -> {
                Game.sExistentBlocks[mRow.intValue + 2][mLine.intValue + 2].mUsed = true
                Game.sExistentBlocks[mRow.intValue + 1][mLine.intValue + 2].mUsed = true
                Game.sExistentBlocks[mRow.intValue + 1][mLine.intValue + 1].mUsed = true
                Game.sExistentBlocks[mRow.intValue][mLine.intValue + 1].mUsed = true
                Game.sExistentBlocks[mRow.intValue + 2][mLine.intValue + 2].mColor = mColor
                Game.sExistentBlocks[mRow.intValue + 1][mLine.intValue + 2].mColor = mColor
                Game.sExistentBlocks[mRow.intValue + 1][mLine.intValue + 1].mColor = mColor
                Game.sExistentBlocks[mRow.intValue][mLine.intValue + 1].mColor = mColor
            }
            else -> {}
        }
    }

    /**
     * 下落。
     * @return 成功则返回 true，否则返回 false
     */
    override fun moveDown(): Boolean {
        when (mShape.value) {
            Shape.ONE -> {
                if (mRow.intValue == 17) {
                    this.handleCannotMoveDown()
                    return false
                }
                if (Game.sExistentBlocks[mRow.intValue + 3][mLine.intValue].mUsed ||
                    Game.sExistentBlocks[mRow.intValue + 3][mLine.intValue + 1].mUsed ||
                    Game.sExistentBlocks[mRow.intValue + 2][mLine.intValue + 2].mUsed) {
                    this.handleCannotMoveDown()
                    return false
                }
            }
            Shape.TWO -> {
                if (mRow.intValue == 17) {
                    this.handleCannotMoveDown()
                    return false
                }
                if (Game.sExistentBlocks[mRow.intValue + 2][mLine.intValue + 1].mUsed ||
                    Game.sExistentBlocks[mRow.intValue + 3][mLine.intValue + 2].mUsed) {
                    this.handleCannotMoveDown()
                    return false
                }
            }
            else -> {}
        }

        return super.moveDown()
    }

    /**
     * 左移。
     */
    override fun moveLeft() {
        when (mShape.value) {
            Shape.ONE -> {
                if (mLine.intValue == 0) {
                    return
                }
                if (Game.sExistentBlocks[mRow.intValue + 1][mLine.intValue].mUsed ||
                    Game.sExistentBlocks[mRow.intValue + 2][mLine.intValue - 1].mUsed) {
                    return
                }
            }
            Shape.TWO -> {
                if (mLine.intValue == -1) {
                    return
                }
                if (Game.sExistentBlocks[mRow.intValue][mLine.intValue].mUsed ||
                    Game.sExistentBlocks[mRow.intValue + 1][mLine.intValue].mUsed ||
                    Game.sExistentBlocks[mRow.intValue + 2][mLine.intValue + 1].mUsed) {
                    return
                }
            }
            else -> {}
        }

        super.moveLeft()
    }

    /**
     * 右移。
     */
    override fun moveRight() {
        when (mShape.value) {
            Shape.ONE -> {
                if (mLine.intValue == 7) {
                    return
                }
                if (Game.sExistentBlocks[mRow.intValue + 1][mLine.intValue + 3].mUsed ||
                    Game.sExistentBlocks[mRow.intValue + 2][mLine.intValue + 2].mUsed) {
                    return
                }
            }
            Shape.TWO -> {
                if (mLine.intValue == 7) {
                    return
                }
                if (Game.sExistentBlocks[mRow.intValue][mLine.intValue + 2].mUsed ||
                    Game.sExistentBlocks[mRow.intValue + 1][mLine.intValue + 3].mUsed ||
                    Game.sExistentBlocks[mRow.intValue + 2][mLine.intValue + 3].mUsed) {
                    return
                }
            }
            else -> {}
        }

        super.moveRight()
    }

    /**
     * 获取顶端所在的行数。顶端是指方块最上方的有效格。
     */
    override val top: Int
        get() {
            if (mShape.value == Shape.ONE) {
                return mRow.intValue + 1
            }
            return mRow.intValue
        }

    /**
     * 变形。
     */
    override fun transform() {
        when (mShape.value) {
            Shape.ONE -> {
                if (mRow.intValue == -1) {
                    return
                }
                if (Game.sExistentBlocks[mRow.intValue][mLine.intValue + 1].mUsed ||
                    Game.sExistentBlocks[mRow.intValue + 2][mLine.intValue + 2].mUsed) {
                    return
                }
                mBlocks[2][1].mUsed = false
                mBlocks[2][0].mUsed = false
                mBlocks[2][2].mUsed = true
                mBlocks[0][1].mUsed = true
                mShape.value = Shape.TWO
            }
            Shape.TWO -> {
                if (mLine.intValue == -1) {
                    return
                }
                mBlocks[2][1].mUsed = true
                mBlocks[2][0].mUsed = true
                mBlocks[2][2].mUsed = false
                mBlocks[0][1].mUsed = false
                mShape.value = Shape.ONE
            }
            else -> {}
        }
    }
}
